#include <string>
#include <fstream>
#include <iostream>
#include "Mepa.h"

void about()
{
    std::cout << " ----------------------------------------" << std::endl;
    std::cout << "  Trabalho de Compilador                 " << std::endl;
    std::cout << "   Alunos: Luiz Gustavo Castilho Martins " << std::endl;
    std::cout << "           Paulo Cesar Ferreira          " << std::endl;
    std::cout << " ----------------------------------------" << std::endl;
}

void help()
{
    std::cout << " -----------------------------------------------------" << std::endl;
    std::cout << " Parametros:                                          " << std::endl;
    std::cout << "  -D n : tamanho n da memoria do registrador de base  " << std::endl;
    std::cout << "  -M n : tamanho n da memoria de dados                " << std::endl;
    std::cout << "  -P n : tamanho n da memoria de programa             " << std::endl;
    std::cout << "  -I n : mostra os membros da equipe                  " << std::endl;
    std::cout << "  -R arquivo : arquivo onde sera colocado o resultado " << std::endl;
    std::cout << "     da instrucao MOSM, se esta opcao nao for usada a " << std::endl;
    std::cout << "     saida sera gerada na saida padrao                " << std::endl;
    std::cout << "  arquivo.mep: arquivo \"executavel\", contendo as    " << std::endl;
    std::cout << "     instruções MEPA                                  " << std::endl;
    std::cout << " -----------------------------------------------------" << std::endl;
}

int main(int argc, char **argv)
{
    int  tamanhoPrograma    = -1;
    int  tamanhoMemoria     = -1;
    int  tamanhoRegistrador = -1;
    int  indiceArquivo      = -1;
    char saida[30];
    Mepa *mepa              = NULL;

    saida[0] = 0;

    // verifica se existe pelo menor um argumento
    if (argc < 2)
    {
        std::cout << "Uso incorreto do programa.";
        return 0;
    }
    else
    {
        // percorre todos os argumentos
        for (int i = 1; i < argc; i++)
        {
            // verifica se eh algum dos parametros do programa
            if (argv[i][0] == '-' && strlen(argv[i]) == 2)
            {
                switch (argv[i][1])
                {
                    case 'P': tamanhoPrograma    = (i + 1 < argc ? atoi(argv[i+1]) : -1); break;
                    case 'D': tamanhoRegistrador = (i + 1 < argc ? atoi(argv[i+1]) : -1); break;
                    case 'M': tamanhoMemoria     = (i + 1 < argc ? atoi(argv[i+1]) : -1); break;
                    case 'R': if (i + 1 < argc) strcpy(saida, argv[i+1]);                 break;
                    case 'I': about(); break;
                    case '?': help();  break;
                }
            }
            else
            {
                // verifica se eh o arquivo do codigo mepa
                indiceArquivo = (argv[i - 1][0] != '-' && indiceArquivo == -1 ? i : indiceArquivo);
            }
        }
    }
    
    // verifica se foi passado um nome de arquivo
    if (indiceArquivo != -1)
        mepa = new Mepa(argv[indiceArquivo], saida, tamanhoPrograma, tamanhoMemoria, tamanhoRegistrador);
    else
    {
        std::cout << "--------------------------------------------------" << std::endl;
        std::cout << "                         E R R O !                " << std::endl;
        std::cout << " Arquivo de entrada nao indicado.                 " << std::endl;
        std::cout << "--------------------------------------------------" << std::endl;
        exit(1);
    }

    // verifica se o mepa foi instanciado
    if (mepa != NULL)
    {
        //mepa->exibirCodigo();
        mepa->executar();
    }

    return 0;
}
